#include <linux/init.h>
#include <linux/module.h>
#include <linux/blkdev.h>
#include <linux/mm.h>
#include <linux/namei.h>

static char buf[] = "你好";
static char buf1[10];

static int file_remove(char* filename)
{
	int retval = 0;
	struct nameidata nd;
	struct dentry *dentry;

	retval = path_lookup(filename, LOOKUP_PARENT, &nd);
	if(retval != 0) 
	{
         return -ENOENT;
	}
	
	dentry = lookup_one_len(nd.last.name, nd.path.dentry, strlen(nd.last.name));
	if (IS_ERR(dentry))
	{ 
		//path_release(&nd);
		return -EACCES;
	}
	
	if(vfs_unlink(nd.path.dentry->d_inode, dentry) != 0)
	{
		printk(KERN_ERR "unlink failed.\n");
	}

	dput(dentry);
	//path_release(&nd);

	return 0;
}

static bool file_is_exist(const char* filename)
{
	mm_segment_t fs = {0};
	struct kstat stat = {0};
	int retval = 0;

	fs = get_fs();
    set_fs(KERNEL_DS);
	retval = vfs_stat((char*)filename, &stat);
    set_fs(fs);
	
	if(retval == 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}

int __init hello_init(void)
{
    struct file *fp;
    mm_segment_t fs;
    loff_t pos;
	const char* filename="/home/kernel_file";

	if(file_is_exist(filename))
	{
		printk(KERN_ERR"file:%s is exist", filename);
	}
	else
	{
		printk(KERN_ERR"file:%s does not exist\n", filename);
	}
    printk("hello enter\n");
    fp = filp_open(filename, O_RDWR | O_CREAT, 0644);
    if (IS_ERR(fp)) {
        printk("create file error\n");
        return -1;
    }

	if(file_is_exist(filename))
	{
		printk(KERN_ERR"file:%s is exist\n", filename);
	}
	else
	{
		printk(KERN_ERR"file:%s does not exist\n", filename);
	}
    fs = get_fs();
    set_fs(KERNEL_DS);
    pos = 0;
    vfs_write(fp, buf, sizeof(buf), &pos);
    pos = 0;
    vfs_read(fp, buf1, sizeof(buf), &pos);
    printk("read: %s\n", buf1);
    filp_close(fp, NULL);
    set_fs(fs);

	printk(KERN_ERR"remove %s\n", filename);
	file_remove("/home/kernel_file");
	if(file_is_exist(filename))
	{
		printk(KERN_ERR"file:%s is exist", filename);
	}
	else
	{
		printk(KERN_ERR"file:%s doest not exist.\n", filename);
	}
    return 0;
}
void __exit hello_exit(void)
{
    printk("hello exit\n");
}
 
module_init(hello_init);
module_exit(hello_exit);
 
MODULE_LICENSE("GPL");
